home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
ae.lha
/
ae
/
AE
/
ae-buffer.c
next >
Wrap
C/C++ Source or Header
|
1990-02-28
|
4KB
|
150 lines
/* AE program profiling system.
Startup and termination code and routines to manipulate AE buffer.
Copyright (C) 1989, 1990 by James R. Larus (larus@cs.wisc.edu)
This file must be compiled by GCC!
AE and AEC are free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
AE and AEC are distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to James R.
Larus, Computer Sciences Department, University of Wisconsin--Madison,
1210 West Dayton Street, Madison, WI 53706, USA or to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* $Header: /var/home/larus/AE/AE/RCS/ae-buffer.c,v 2.0 90/02/09 17:18:53 larus Exp Locker: larus $ */
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "ae.h"
#include "ae-machine.h"
/* Save pointer to beginning of AE buffer. */
char *ae_buffer_base;
/* Register or variable pointing to next free byte in AE buffer. */
#ifdef AE_BUFFER_REG
register char *ae_bp asm (AE_BUFFER_REG);
#elif AE_BUFFER_VAR
char *ae_bp;
#endif
/* Register or variable pointing to end of AE buffer. */
#ifdef AE_BUFFER_BOUND_REG
register char *ae_bound asm(AE_BUFFER_BOUND_REG);
#elif AE_BUFFER_BOUND_VAR
char *ae_bound;
#endif
/* File descriptor for writing AE buffer. */
int ae_fd;
/* Stack pointer upon entry to AE_INITIALIZE. */
static char *old_sp;
/* Initialize by allocating AE buffer on the stack and opening the
output file. Invoked by AE_START (which is written in assembly
language). Return the new stack pointer. */
char *
ae_initialize (argc, argv) /* Define main's parameters for compiler */
int argc;
char *argv[];
{
register char *sp asm (SP_REG);
struct rlimit rl;
/* Raise stacksize limit. */
getrlimit (RLIMIT_STACK, &rl);
rl.rlim_cur = rl.rlim_max;
setrlimit (RLIMIT_STACK, &rl);
ae_fd = open ("ae.out", O_WRONLY | O_CREAT | O_TRUNC, 0644);
/* Make space on stack for AE buffer */
#ifdef AE_BUFFER_STACK_OFFSET
ae_buffer_base =
(char *) (STACK_TOP - (AE_BUFFER_SIZE + AE_BUFFER_STACK_OFFSET));
#else
ae_buffer_base = (char *) (sp - AE_BUFFER_SIZE);
#endif
ae_bp = ae_buffer_base;
#if (defined (AE_BUFFER_BOUND_REG) || defined(AE_BUFFER_BOUND_VAR))
ae_bound = ae_bp + AE_BUFFER_SIZE - CHUNK_SIZE;
#endif
old_sp = sp;
*ae_bp = 0; /* Force OS to extend stack */
return (sp = (ae_buffer_base - AE_START_FRAME_SIZE));
}
/* Flush AE buffer by writing its contents to a file and reset the
buffer pointer. This routine probably must be written in assembly
language since it cannot affect ANY register visible to its caller
(not just the callee-saved registers) since it is called at arbitrary
points in a function. */
#ifdef USE_C_FLUSH_BUFFER
void
ae_flush_buffer ()
{
char *x[32]; /* Space to store registers */
x[0] = ae_bp; /* Example */
write (ae_fd, ae_buffer_base, (int) ae_bp - (int) ae_buffer_base);
ae_bp = ae_buffer_base;
#ifdef (defined (AE_BUFFER_BOUND_REG) || defined (AE_BUFFER_BOUND_VAR))
ae_bound = ae_bp + AE_BUFFER_SIZE - 4;
#endif
}
#endif
/* Clean up at program termination by flushing the remaining events. */
void
ae_terminate ()
{
register char *sp asm (SP_REG);
ae_flush_buffer ();
close (ae_fd);
/* Restore the stack pointer. */
sp = old_sp;
}
/* Redefine the EXIT routine to call AE_TERMINATE. */
exit (code)
int code;
{
ae_terminate ();
_cleanup ();
_exit (code);
}